<?php

/**
 * Contains a function to validate an email address.
 *
 * PHP Version 5
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */

/** @uses valueOf For safe handling of arrays. */
require_once 'function_valueof.php';

/**
 * A function to validate an email address.
 *
 * @param string $email The email address to validate.
 *
 * @access public
 * @return bool         True if the email address is valid, false if not.
 */
function validEmail($email)
{
    /** Gets the position of the @ symbol. */
    $atpos = strrpos($email, '@');
 
    /** Determines if there is an @ symbol in the address - returns false if not. */
    if ($atpos === false) {
        return false;
    }

    /**
     * Stores the domain and the local values, as well as their lengths, 
     * for comparison against email address standards.
     */
    $domain = substr($email, $atpos + 1);
    $local = substr($email, 0, $atpos);
    $localLength = strlen($local);
    $domainLength = strlen($domain);
    $localWithoutBackslashes = str_replace('\\\\', '', $local); 

    /** Stores comparision conditionals. */
    $invalidLocalLength = ($localLength < 1 || $localLength > 64);
    $invalidDomainLength = ($domainLength < 1 || $domainLength > 255); 
    $localBeginsWithPeriod = (valueOf($local, 0) == '.'); 
    $localEndsWithPeriod = (valueOf($local, $localLength - 1) == '.');
    $invalidSlashesInLocal = (preg_match('/\\.\\./', $local));
    $invalidDomain = (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain));
    $invalidSlashesInDomain = (preg_match('/\\.\\./', $domain));
    $validCharacters = (!preg_match(
        '/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', 
        $localWithoutBackslashes
    ));
    $invalidQuotes = (!preg_match(
        '/^"(\\\\"|[^"])+"$/', 
        $localWithoutBackslashes
    )); 
    
    /** If email address standards are violated, return false. */
    if ($invalidLocalLength || $invalidDomainLength 
        || $invalidSlashesInLocal || $invalidSlashesInDomain 
        || $localBeginsWithPeriod || $localEndsWithPeriod
        || $invalidDomain
        || ($validCharacters && $invalidQuotes)
    ) {
        return false;
    }

    /** Checks to see if the domain actually exists using DNS. */
    if (!(checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A'))) {
        return false;
    }
  
    /** All checks passed - returning true. */
    return true;
}

?>